const isLittleEndian = true;

/****frames come from websocket */
const FRAME_CONFIG              = 0x68643030;
const FRAME_AUDIO               = 712;
const FRAME_GPS                 = 0x73706730;
const FRAME_END                 = 0x481;

//codec.js
const REQUEST_CODEC_D_DATA       = 0x6002;


const REQUEST_CONNECT_NEW        = 0x2001;
const REQUEST_CONNECT_SEND_AUDIO_DATA = 0x2002;

const RESPONSE_CONNECT_CLOSE       = 0x2102;
const RESPONSE_CONNECT_ERROR       = 0x2103;
const RESPONSE_CONNECT_PROGRESS    = 0x2104;
const RESPONSE_CONNECT_WSERROR     = 0x2105;
const RESPONSE_CONNECT_DONE        = 0x2106;
const RESPONSE_CONNECT_READY       = 0x2107;
const RESPONSE_CONNECT_GPS_DATA    = 0x2109;
const RESPONSE_CONNECT_SUCCESS     = 0x2112;
const RESPONSE_CONNECT_MEMBER_LEAVE = 0x2120;

const RESPONSE_CONNECT_ERROR_GROUPFULL     = 0x2121
const RESPONSE_CONNECT_ERROR_MEMBERTALKING          = 0x2122

var isReceive711Flag = false;

var _release = function(){
    this.websocket && this.websocket.close();
    self.close();
    console.info("connector.js release...")
}

var _array2StringList = function(data,offset,length){
    console.info('data',data,offset,length)
    let view = new Uint8Array(data);
    let result = [];
    var dataString = "";
    var cc ;
    for (let i = offset; i < length; i++) {
        if(view[i] !== 0){
            cc = String.fromCharCode(view[i]);
            console.info("ccSTART",cc,view[i],String.fromCharCode(view[i]))
            console.info("dataString",dataString)
            if (cc == '|'){
                result.push(dataString)
                dataString = ""
            }else {
                dataString += cc
            }
        }else {
            result.push(dataString)
            dataString = ""
        }

        console.info("ccEND",cc == "|",dataString.length)
        // dataString += cc;

    }
    // result.push(dataString)
    console.info("进入_array2StringList",result)
    return result;
}


var onWebSocketError = function(event){
    self.postMessage({
        type:RESPONSE_CONNECT_WSERROR,
    });
    this.websocket && this.websocket.close()
    this.websocket = null;
}
var onWebSocketClosed = function(){
    self.postMessage({
        type:RESPONSE_CONNECT_CLOSE,
    });
    this.websocket && this.websocket.close()
    this.websocket = null;
}
var onWebSocketOpened = function(event){
    console.info("connect onwebSocketopened");
    this.websocket.send(this.playParams);
}

var onWebSocketMessage = function(event){
    var data = event.data;
    console.info("_onWebSocketMessage",data);
    if(data == "") return ;
    var dataView = new DataView(data)
    var n = 0;
    var type = dataView.getInt32(n,isLittleEndian);
    var length = dataView.getInt32((++n) * 4,isLittleEndian);
    var errCode = dataView.getInt32((++n) * 4,isLittleEndian);
    var frameType = dataView.getInt32((++n) * 4,isLittleEndian);
    var param2 = dataView.getInt32((++n) * 4,isLittleEndian);

    console.info("type=",type,"length=",length,"errCode=",errCode,"frameType=",frameType,"param2=",param2);

    switch(type){
        case 711:
            if(isReceive711Flag) return ;
            console.info("frameType:",frameType)
            if(frameType != 0){
                var data = this.array2StringList(data,20,length);
                if (frameType == 1){
                    self.postMessage({
                        type:RESPONSE_CONNECT_ERROR_GROUPFULL,
                        errno:frameType,
                        data:data
                    });
                }else if(frameType == 2){
                    self.postMessage({
                        type:RESPONSE_CONNECT_ERROR_MEMBERTALKING,
                        errno:frameType,
                        data:data
                    });
                }else {
                    self.postMessage({
                        type:RESPONSE_CONNECT_ERROR,
                        errno:frameType,
                        data:data
                    });
                }
                console.info("the device is busy or file is not existed. errno is ",frameType);
                return;
                //this._requestStreamFailed("the device is busy or file is not existed. errno is " + frameType);
            }
            isReceive711Flag = true;
            self.postMessage({
                type:RESPONSE_CONNECT_SUCCESS,
            });
            break;
        // case 1041://new a clusterintercom
        //     var data = this.array2StringList(data,20,length-20);
        //     self.postMessage({
        //         type:RESPONSE_CONNECT_ERROR,
        //         errno:frameType,
        //         data:data
        //     });
        //     console.info("new a clusterintercom failed,the device is busy");
        //     return;
        case 1042://single member leave
           var data = this.array2StringList(data,20,length);
           self.postMessage({
                type:RESPONSE_CONNECT_MEMBER_LEAVE,
                data:data
            });
            console.info("single member leave ",frameType);
            return;
        case 1039://members dismiss
            self.postMessage({
                type:RESPONSE_CONNECT_CLOSE,
                errno:frameType
            });
            console.info("members dismiss ");
            return;
    }

    if(data.byteLength >= length) this.parseWebSocketMessage(type,dataView,length,data);

}


var _parseWebSocketMessage = function(type,dataView,length,data){
    var postData = null;
    switch(type){
      case  FRAME_AUDIO:{
        var cut = 20;
        if(this.isAudioTypeG711) cut += 4;
        var postData = {
            type:REQUEST_CODEC_D_DATA,
            data:data.slice(cut)
         };
         self.postMessage(postData,[postData.data]);
         break;
      }
      case FRAME_GPS:{
        /*var latitudeDegree = dataView.getUint8(n);
        var latitudeCent = dataView.getUint8(++n);
        var longitudeDegree = dataView.getUint8(++n);
        var longitudeCent = dataView.getUint8(++n);
        var latitudeSec = dataView.getInt32(++n,true);
        n += 4;
        var longitudeSec = dataView.getInt32(n,true);
        var tmplongitude =  parseFloat(longitudeCent  / 60.00) * 10000000   + parseFloat(longitudeSec / 3600.00);
        var tmplatitude = parseFloat(latitudeCent  / 60.00) * 10000000  + parseFloat(latitudeSec / 3600.00);
        var longitude = parseFloat(longitudeDegree+"."+parseInt(tmplongitude));
        var latitude = parseFloat(latitudeDegree+"."+parseInt(tmplatitude));
        n = 88;
        const years = dataView.getUint16(n,isLittleEndian);
        n += 2;
        var  month = dataView.getUint8(n);
        var  days = dataView.getUint8(++n);
        var  hours = dataView.getUint8(++n);
        var  minutes = dataView.getUint8(++n);
        var  seconds = dataView.getUint8(++n);
        var timestamp = years + "-" + ((month >9) ? month: "0"+month) + '-' +((days >9) ? days: "0"+days) +
            " " + ((hours >9) ? hours: "0"+hours) + ":" + ((minutes >9) ? minutes: "0"+minutes) + ":" + ((seconds >9) ? seconds: "0"+seconds)
        console.info("GPS",pts,timestamp,latitude,longitude);
        var postData = {
            type:RESPONSE_CONNECT_GPS_DATA,
            pts:pts,             //playtime
            timestamp:timestamp, //createTime
            latitude:latitude,
            longitude:longitude
        };
        self.postMessage(postData);
        break;*/
      }
      default :
      {
        console.info("ignore msg type=",type,"length=",length);
      }

    }
}

var sendAudio = function(data){
    var newArray = new ArrayBuffer(data.length + 20);
    var newBuffer = new Uint8Array(newArray);
    newBuffer.set(data,20);
    var dataView = new DataView(newArray);
    dataView.setInt32(0,712,isLittleEndian);
    dataView.setInt32(4,data.length + 20,isLittleEndian);
    dataView.setInt32(8,0,isLittleEndian);
    dataView.setInt32(12,0,isLittleEndian);
    dataView.setInt32(16,0,isLittleEndian);
    this.websocket && this.websocket.send(newArray);
    console.info("send audio.... ",newBuffer.byteLength);
    console.info(data);
    console.info(newArray);
}



var startWebsocket = function(){
    console.info("_startWebsocket",this.url);
    this.websocket = new WebSocket(this.url);
    this.websocket.binaryType = 'arraybuffer';
    this.websocket.onmessage = onWebSocketMessage.bind(this);
    this.websocket.onclose = onWebSocketClosed.bind(this);
    this.websocket.onerror = onWebSocketError.bind(this);
    this.websocket.onopen = onWebSocketOpened.bind(this);
}

var Connector = function(option){
    this.url = option.url;
    this.playParams = option.playParams;
    this.websocket = null;
    this.isInited = false;
    this.isAudioTypeG711 = option.audioType == 0;
    this.startWebsocket();
};

var _FN = Connector.prototype;

var _attributes = {
    /** start websocket */
    sendAudio:sendAudio,
    startWebsocket:startWebsocket,
    onWebSocketError:onWebSocketError,
    onWebSocketClosed:onWebSocketClosed,
    onWebSocketOpened:onWebSocketOpened,
    onWebSocketMessage:onWebSocketMessage,
    parseWebSocketMessage:_parseWebSocketMessage,
    /** end websocket */
    release:_release,
    array2StringList:_array2StringList
};

for(var key in _attributes){
   _FN[key] =  _attributes[key];
}

var FR = null;
self.onmessage = function (res){
    data = res.data;
    switch(data.type){
       case REQUEST_CONNECT_NEW:
            FR = new Connector(data.option);
            break;
       case REQUEST_CONNECT_SEND_AUDIO_DATA:
            FR && FR.sendAudio(data.data);
       /*case REQUEST_CONNECT_RELEASE:
            if(FR == null)return ;
            FR.release();
            FR = null;
            break;*/
    }
};

self.postMessage({
    type:RESPONSE_CONNECT_READY
});
